using System.Collections.Generic;
using LogSystem;
using UnityEngine;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.City
{
    public class CityRealAiGoodsController : CityRealAiRoleControllerBase
    {
        /// <summary>
        /// Uid 计数器
        /// </summary>
        private static int ROLE_UID_INDEX = 0;
        public int GoodsType { get; }

        private Dictionary<int, List<CityRealAiEventPointInfo>> _eventPointGroupDic;

        public List<CityRealAiEventPointInfo> EventPointList { get; }

        private string _goodsName;

        /// <summary>
        /// 对应解锁建筑ID （0表示本房间）
        /// </summary>
        public int UnlockBuildId => _unlockBuildId;
        private int _unlockBuildId;

        /// <summary>
        /// 对应解锁等级
        /// </summary>
        public int UnlockLevel => _unlockLevel;
        private int _unlockLevel;
        
        /// <summary>
        /// 对应设施ID
        /// </summary>
        public int FacilityId => _facilityId;
        private int _facilityId;

        /// <summary>
        /// 固定交互物动画
        /// </summary>
        private Animator _goodsAni;

        /// <summary>
        /// 生成的交互物
        /// </summary>
        public Dictionary<string, GameObject[]> MoveGoodsDic { get; private set; }
        
        /// <summary>
        /// 生成交互物现存数量
        /// </summary>
        public int MoveGoodsCount { get; private set; }
        
        public CityRealAiGoodsController(int birthContainerId,  CityRealAiContainerManagerBase containerMgr, int goodsType) : base(birthContainerId)
        {
            EventPointList = new List<CityRealAiEventPointInfo>();
            _eventPointGroupDic = new Dictionary<int, List<CityRealAiEventPointInfo>>();
            GoodsType = goodsType;
        }

        public void SetupGoodsName(string goodsName)
        {
            _goodsName = goodsName;
        }
        
        public void SetupUnlockBuildId(int unlockBuildId)
        {
            _unlockBuildId = unlockBuildId;
        }

        public void SetupUnlockLevel(int unlockLevel)
        {
            _unlockLevel = unlockLevel;
        }
        
        public void SetupFacilityId(int facilityId)
        {
            _facilityId = facilityId;
        }

        public void UpdateGoods()
        {
            if (string.IsNullOrEmpty(_goodsName))
            {
                return;
            }
            
            if (_containerMgr.RoomRootTran == null)
            {
                return;
            }

            // 注意find层数layer，交互物嵌的太深可能找不到
            var goodsObj = Find(_containerMgr.RoomRootTran, _goodsName, 3);
            if (goodsObj == null)
            {
                return;
            }
            _roleObj = goodsObj.gameObject;
            _goodsAni = _roleObj.GetComponentInChildren<Animator>();
        }

        public CityRealAiEventPointInfo SetupEventPoint(ref CityRealAiEventPointConfig pointConfig)
        {
            var pointInfo = new CityRealAiEventPointInfo(this);
            pointInfo.UpdatePointCfg(ref pointConfig);
            EventPointList.Add(pointInfo);
            if (!_eventPointGroupDic.TryGetValue(pointConfig.EventGroup, out var pointInfoList))
            {
                pointInfoList = new List<CityRealAiEventPointInfo>();
                _eventPointGroupDic.Add(pointConfig.EventGroup, pointInfoList);
            }
            pointInfoList.Add(pointInfo);
            SetupMoveGoods(ref pointConfig);
            return pointInfo;
        }

        private void SetupMoveGoods(ref CityRealAiEventPointConfig pointConfig)
        {
            if (string.IsNullOrEmpty(pointConfig.MoveGoodsName))
            {
                return;
            }
            
            if (MoveGoodsDic == null)
            {
                MoveGoodsDic = new Dictionary<string, GameObject[]>();
            }

            if (!MoveGoodsDic.TryGetValue(pointConfig.MoveGoodsName, out var moveGoodsArray))
            {
                moveGoodsArray = new GameObject[pointConfig.MoveGoodsPosList.Length];
                MoveGoodsDic.Add(pointConfig.MoveGoodsName, moveGoodsArray);
            }
        }

        public void UpdatePerformer(int eventGroup, CityRealAiNpcController performer)
        {
            if (_eventPointGroupDic.TryGetValue(eventGroup, out var pointInfoList))
            {
                for (int i = 0; i < pointInfoList.Count; i++)
                {
                    pointInfoList[i].UpdatePerformer(performer);
                }
            }
        }

        public GameObject GetMoveGoods(string moveGoodsName)
        {
            if (MoveGoodsDic == null || MoveGoodsDic.Count <= 0)
            {
                return null;
            }
            
            if (MoveGoodsDic.TryGetValue(moveGoodsName, out var moveGoodsArray))
            {
                for (int i = 0; i < moveGoodsArray.Length; i++)
                {
                    var moveGoods = moveGoodsArray[i];
                    if (moveGoods != null)
                    {
                        moveGoodsArray[i] = null;
                        MoveGoodsCount--;
                        return moveGoods;
                    }
                }
            }

            return null;
        }

        public int OnUpdateMoveGoods(string moveGoodsName, GameObject moveGoodsObj)
        {
            if (MoveGoodsDic == null || MoveGoodsDic.Count <= 0)
            {
                return -1;
            }
            
            if (MoveGoodsDic.TryGetValue(moveGoodsName, out var moveGoodsArray))
            {
                for (int moveGoodspos = 0; moveGoodspos < moveGoodsArray.Length; moveGoodspos++)
                {
                    if ( moveGoodsArray[moveGoodspos] == null)
                    {
                        MoveGoodsCount++;
                        moveGoodsArray[moveGoodspos] = moveGoodsObj;
                        return moveGoodspos;
                    }
                }
            }

            return -1;
        }
        
        private Transform Find(Transform target, string name, int layer = 0)
        {
            for (int i = 0; i < target.childCount; i++)
            {
                var child = target.GetChild(i);
                if (child.name == name)
                {
                    return child;
                }

                if (layer > 0)
                {
                    var subChild = Find(child.transform, name, (layer - 1));
                    if (subChild == null)
                    {
                        continue;
                    }
                    
                    return subChild;
                }
            }
            
            return null;
        }

        public void TriggerAnimation(string aniName)
        {
            if (_goodsAni != null)
            {
                _goodsAni.enabled = true;
                _goodsAni.SetTrigger(aniName);
            }
        }

        public void ResetTriggerAnimation()
        {
            if (_goodsAni != null)
            {
                _goodsAni.Play("Idle");
                Timers.inst.CallLater((o) =>
                {
                    if (_goodsAni != null)
                    {
                        _goodsAni.enabled = false;
                    }
                });
            }
        }

        public CityRealAiEventPointInfo GetEventPoint(int uid, int eventId, CityRealEventPointState state)
        {
            for (int i = 0; i < EventPointList.Count; i++)
            {
                var eventPoint = EventPointList[i];
                if (eventPoint.PointConfig.eventId == eventId)
                {
                    if (GetEventPoint(uid, state, eventPoint))
                        return eventPoint;
                }
            }

            return null;
        }

        public CityRealAiEventPointInfo GetEventPoint(int uid, int eventId, CityRealEventPointState state1, CityRealEventPointState state2)
        {
            for (int i = 0; i < EventPointList.Count; i++)
            {
                var eventPoint = EventPointList[i];
                if (eventPoint.PointConfig.eventId == eventId)
                {
                    if (GetEventPoint(uid, state1, eventPoint))
                        return eventPoint;

                    if (GetEventPoint(uid, state2, eventPoint))
                        return eventPoint;
                }
            }

            return null;
        }

        public CityRealAiEventPointInfo GetEventPoint(int uid, int eventId, CityRealEventPointState state1, CityRealEventPointState state2, CityRealEventPointState state3)
        {
            for (int i = 0; i < EventPointList.Count; i++)
            {
                var eventPoint = EventPointList[i];
                if (eventPoint.PointConfig.eventId == eventId)
                {
                    if (GetEventPoint(uid, state1, eventPoint))
                        return eventPoint;

                    if (GetEventPoint(uid, state2, eventPoint))
                        return eventPoint;

                    if (GetEventPoint(uid, state3, eventPoint))
                        return eventPoint;
                }
            }

            return null;
        }

        public CityRealAiEventPointInfo GetEventPoint(int uid, int eventId, params CityRealEventPointState[] stateList)
        {
            Debug.LogErrorFormat("GetEventPoint真的会有{0}个参数么，有装箱", stateList.Length);

            for (int i = 0; i < EventPointList.Count; i++)
            {
                var eventPoint = EventPointList[i];
                if (eventPoint.PointConfig.eventId == eventId)
                {
                    for (int j = 0; j < stateList.Length; j++)
                    {
                        var state = stateList[j];
                        if (GetEventPoint(uid, state, eventPoint)) 
                            return eventPoint;
                    }
                }
            }

            return null;
        }

        private static bool GetEventPoint(int uid, CityRealEventPointState state, CityRealAiEventPointInfo eventPoint)
        {
            if (state == CityRealEventPointState.Idle)
            {
                // 没有执行者，或者执行者是自己时，该事件点可执行新的事件。
                if (eventPoint.State == state &&
                    (eventPoint.Performer == null ||
                     eventPoint.Performer.Uid == uid ||
                     eventPoint.EventConfig.parameter == CityRealAiConst.NpcActiveTag ||
                     eventPoint.EventConfig.parameter == CityRealAiConst.NpcHideTag))
                {
                    return true;
                }
            }
            else
            {
                // 有执行者时，执行人不能时自己。
                if (eventPoint.State == state && eventPoint.Performer != null && eventPoint.Performer.Uid != uid)
                {
                    return true;
                }
            }

            return false;
        }

        public bool CheckEventDemand(Vector2[] demandList)
        {
            if (demandList.Length <= 0)
            {
                return false;
            }
            
            for (int i = 0; i < demandList.Length; i++)
            {
                var condition = demandList[i];
                if ((int) condition.x == (int)CityRealEventConditionType.ExistEvent)
                {
                    var eventInfo = GetEventPoint(Uid, (int)condition.y, CityRealEventPointState.Work, CityRealEventPointState.Wait);
                    if (eventInfo == null)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public bool CheckExistMoveGoods(string moveGoodsName, int uid, int eventId, CityRealEventPointState state)
        {
            if (MoveGoodsDic == null || MoveGoodsDic.Count <= 0)
            {
                return false;
            }
            
            if (MoveGoodsDic.TryGetValue(moveGoodsName, out var moveGoodsArray))
            {
                for (int moveGoodspos = 0; moveGoodspos < moveGoodsArray.Length; moveGoodspos++)
                {
                    if ( moveGoodsArray[moveGoodspos] != null && GetEventPoint(uid, eventId, state) != null)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public void OnResetEvent()
        {
            for (int i = 0; i < EventPointList.Count; i++)
            {
                EventPointList[i].Reset();
            }

            DestroyMoveGoods();
        }

        private void DestroyMoveGoods()
        {
            if (MoveGoodsDic == null || MoveGoodsDic.Count <= 0)
            {
                return;
            }
            
            foreach (var keyValuePair in MoveGoodsDic)
            {
                for (int i = 0; i < keyValuePair.Value.Length; i++)
                {
                    if (keyValuePair.Value[i] != null)
                    {
                        Object.Destroy(keyValuePair.Value[i]);
                        keyValuePair.Value[i] = null;
                    }
                }
            }
            // MoveGoodsDic.Clear();
        }

        public override void Dispose()
        {
            for (int i = 0; i < EventPointList.Count; i++)
            {
                var eventPoint = EventPointList[i];
                eventPoint.Reset();
            }
            EventPointList.Clear();
            DestroyMoveGoods();
            _goodsName = null;
            _goodsAni = null;
        }
    }
}
